﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using Pixysoft.Framework.Verifications;


namespace Pixysoft.Framework.XSchEmA.Entity
{
    /// <summary>
    /// primary key schema
    /// </summary>
    public class PrimaryKeySchema : IConstraintSchema
    {
        private string indexName;
        private string constraintName;
        private string tableName;
        private List<string> columnNames = new List<string>();

        /// <summary>
        /// index name
        /// </summary>
        [XmlIgnore]
        public string IndexName
        {
            get { return indexName; }
            set { indexName = value; }
        }
        /// <summary>
        /// constraint name
        /// </summary>
        [XmlAttribute]
        public string ConsName
        {
            get { return constraintName; }
            set { constraintName = value; }
        }
        /// <summary>
        /// table name
        /// </summary>
        [XmlAttribute]
        public string TableName
        {
            get { return tableName; }
            set { tableName = value; }
        }
        /// <summary>
        /// column name
        /// </summary>
        [XmlArray]
        public List<string> ColumnNames
        {
            get { return columnNames; }
            set { columnNames = value; }
        }

        TableSchema table;
        List<ColumnSchema> columns = new List<ColumnSchema>();

        /// <summary>
        /// primary key table
        /// </summary>
        [XmlIgnore]
        public TableSchema Table
        {
            get { return table; }
            set { table = value; }
        }
        /// <summary>
        /// primary key columns
        /// </summary>
        [XmlIgnore]
        public List<ColumnSchema> Columns
        {
            get { return columns; }
        }
        /// <summary>
        /// primary key schema
        /// </summary>
        public PrimaryKeySchema()
        {
        }
        /// <summary>
        /// primary key schema
        /// </summary>
        /// <param name="pkName"></param>
        /// <param name="tableName"></param>
        /// <param name="columnNames"></param>
        public PrimaryKeySchema(string pkName, string tableName, params string[] columnNames)
            : this(pkName, tableName, SchemaUtility.ObjectToList<string>(columnNames))
        {
        }
        /// <summary>
        /// primary key schema
        /// </summary>
        /// <param name="pkName"></param>
        /// <param name="table"></param>
        /// <param name="columns"></param>
        public PrimaryKeySchema(string pkName, TableSchema table, params ColumnSchema[] columns)
            : this(pkName, table, SchemaUtility.ObjectToList<ColumnSchema>(columns))
        {
        }
        /// <summary>
        /// primary key schema
        /// </summary>
        /// <param name="pkName"></param>
        /// <param name="tableName"></param>
        /// <param name="columnNames"></param>
        public PrimaryKeySchema(string pkName, string tableName, List<string> columnNames)
        {
            if (columnNames == null || columnNames.Contains(null))
                throw new Exception("004001");

            this.constraintName = pkName;

            this.tableName = tableName;

            this.columnNames = new List<string>();

            foreach (string columnName in columnNames)
                this.columnNames.Add(columnName.ToUpper().Trim());

        }
        /// <summary>
        /// primary key schema
        /// </summary>
        /// <param name="pkName"></param>
        /// <param name="table"></param>
        /// <param name="columns"></param>
        public PrimaryKeySchema(string pkName, TableSchema table, List<ColumnSchema> columns)
        {
            if (table == null)
                throw new Exception("004002");

            if (columns == null || columns.Contains(null))
                throw new Exception("004003");


            this.constraintName = pkName;

            this.table = table;

            this.tableName = table.TableName.Trim().ToUpper();

            this.columnNames = new List<string>();

            this.columns = columns;

            foreach (ColumnSchema column in columns)
                this.columnNames.Add(column.ColumnName.Trim().ToUpper());
        }
        /// <summary>
        /// check primary key schema
        /// </summary>
        public void Inspection()
        {
            if (!Verification.Verifies(constraintName, TableName).IsNotNullOrEmpty().Result())
                throw new Exception("004004");

            if (table == null)
                throw new Exception("004005");

            if (columnNames == null || columnNames.Count == 0)
                throw new Exception("004006");

            if (columns == null || columns.Count == 0)
                throw new Exception("004007");

            if (columns.Count != columnNames.Count)
                throw new Exception("004008");

            constraintName = constraintName.Trim().ToUpper();

            TableName = TableName.Trim().ToUpper();
        }
        /// <summary>
        /// refresh schema by pointer(c++)
        /// </summary>
        public void Refresh()
        {
            if (table == null)
                throw new Exception("004009");

            if (columns == null)
                throw new Exception("004010");

            TableName = table.TableName;

            columnNames = new List<string>();

            foreach (ColumnSchema column in columns)
            {
                column.IsNullable = false;
                ColumnNames.Add(column.ColumnName);
            }

        }
        /// <summary>
        ///  to string
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            StringBuilder builder = new StringBuilder();
            builder.Append(tableName + ":");
            builder.Append(SchemaUtility.ListToString<string>(columnNames));
            return builder.ToString();
        }
        /// <summary>
        /// clone 仅名字clone 不包含指针关系
        /// </summary>
        /// <returns></returns>
        public PrimaryKeySchema Clone()
        {
            return new PrimaryKeySchema(ConsName, TableName, columnNames);

        }

    }
}
